/*!
Png-6
Support for alpha transparent pngs in legacy versions of MS Internet Explorer
Copyright (c) 2009 Pete Boere - pete@the-echoplex.net
MIT style license - http://www.opensource.org/licenses/mit-license.php
*/
(function () {
	
var win = window,
	doc = document, 
	
	self = this.Png6 = {
		
		/**				
		Convert png images in internet explorer 6/5.5. Will not attempt conversion with other browsers
		@method convert
		@param selector { string | htmlelement | nodelist | [htmlelement] } 
		*/    
		convert: function ( selector ) {
	
			if ( !targetBrowser ) {	return; }
			
			// Remove default onload handler
			win.detachEvent( 'onload', autoConvertHandler );
			
			selectorEngine = selectorEngine || pickSelectorEngine();
			
			// Determine the type of argument
			var imgs,
				isObject = !!selector && typeof selector === 'object';
				
			// String
			if ( typeof selector === 'string' ) {
				imgs = ( selectorEngine || doc.getElementsByTagName )( selector );
			}
			// Node lists
			else if ( isObject && !!selector.item && !!selector.length ) {
				imgs = toArray( selector );
			} 
			// Single element
			else if ( isObject && !!selector.nodeName && selector.nodeType === 1 ) {
				imgs = [ selector ];
			}
			// Static array
			else if ( {}.toString.call( selector ) === '[object Array]' ) {
				imgs = selector;
			}
			else {
				return;
			}

			// Ensure image is loaded before processing
			each( imgs, function ( img ) {
				var dummy = new Image;
				dummy.onload = function () { process( img ); };
				dummy.src = img.src;
			});
		},
		
		/**  
		Selects a persistent selector engine for the class via a passed reference
		@method setSelectorEngine
		@param engine { method } a reference to a selector engine method
		@returns class object
		*/ 
		setSelectorEngine: function ( engine ) {
			selectorEngine = engine;
			return self;
		}
	},

/////////////////////////////////////////////////////////////////////////
//  Private
/////////////////////////////////////////////////////////////////////////
	
	pickSelectorEngine = function () {
		return ( win.JELLY && win.JELLY.Q ) || win.jQuery || win.Sizzle || win.$$;
	},
	
	selectorEngine = pickSelectorEngine(),
	
	autoConvertHandler = function () {
		self.convert( doc.images );
	},
	
	targetBrowser = /MSIE (6|5\.5)/i.test( win.navigator.userAgent ),
	
	process = function ( img ) {
		
		// Check to see we're actually dealing with a png image
		if ( !img || !img.nodeName || img.nodeName.toUpperCase() !== 'IMG' || !/\.png$/i.test( img.src ) ) { return; }

		// Create custom elements so as not to inherit any other styles.
		// Two elements are required: 
		//		- An outer element to hold box-model related styles (padding/border)
		//		- An inner element to represent the actual image
		var outerElement = doc.createElement( 'png6-box' ),
			innerElement = doc.createElement( 'png6-img' ),
			currentStyle = img.currentStyle;
		
		// Copy over all style info, box-model properties copy to the outer element only
		for ( var prop in currentStyle ) {
			if ( /^(margin|padding)|^border$|^border[a-z]*width$/i.test( prop ) ) {
				outerElement.style[ prop ] = currentStyle[ prop ];
				innerElement.style[ prop ] = 0;
			}
			else {
				innerElement.style[ prop ] = 
				outerElement.style[ prop ] = currentStyle[ prop ];
			}
		}
		
		// Set specifics for outer element
		setStyle( outerElement, {
			display: propertyIsSet( img, 'display' ) && ( currentStyle.display != 'inline' ) ? 
					currentStyle.display : 'inline-block'
		});			
		
		// Cancel out any style properties that will effect image width measurements
		setStyle( img, {
			border: 0,
			padding: 0
		});
		
		// Set specifics for inner element
		setStyle( innerElement, {
			height: 
				propertyIsSet( img, 'height' ) && ( currentStyle.height != 'auto' ) ? 
					currentStyle.height : img.height + 'px',
			width: 
				propertyIsSet( img, 'width' ) && ( currentStyle.width != 'auto' ) ? 
					currentStyle.width : img.width + 'px',
			display: 'inline-block',
			verticalAlign: 'bottom',
			filter: 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + 
				img.src + '", sizingMethod="scale")',
			position: 'static'
		});
		
		// Copy over any image attributes
		each( [ 'id', 'title' ], function ( attr ) {
			var value = img.getAttribute( attr );
			if ( value !== null ) {
				outerElement.setAttribute( attr, value );		
			}
		}); 
		outerElement.className = img.className;

		// Restore alt text
		if ( !img.alt != '' ) {
			innerElement.innerHTML = '<img alt="' + 
				img.alt + '" style="position:absolute;font-size:13px;left:-999em" />';
		}
		
		// Append the inner element and swap the fragment with original image
		outerElement.appendChild( innerElement );
		img.parentNode.replaceChild( outerElement, img );
	},
	
	propertyIsSet = function ( img, prop ) {
		return img.currentStyle[ prop ] || img.currentStyle[ prop ] == '0';
	},
	
/////////////////////////////////////////////////////////////////////////
//  Helpers
/////////////////////////////////////////////////////////////////////////

	setStyle = function ( el, obj ) {
		for ( var prop in obj ) {
			el.style[ prop ] = obj[ prop ];
		}
	},
	
	toArray = function ( obj ) {
		var result = [], n = obj.length, i = 0;
		for ( ; i < n; i++ ) { 
			result[i] = obj[i]; 
		}
		return result;
	},
	
	each = function ( arr, callback ) {
		for ( var i = 0, n = arr.length; i < n; i++ ) { 
			callback.call( {}, arr[i], i ); 
		}
	};
	

// Set up onload handler by default  
if ( targetBrowser ) {
	win.attachEvent( 'onload', autoConvertHandler );
}


})();